package com.elysia.newsservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.elysia.newsservice.domain.dto.UpdateLogDTO;
import com.elysia.newsservice.domain.dto.VersionJoinDTO;
import com.elysia.newsservice.domain.entity.GameVersion;
import com.elysia.newsservice.domain.entity.VersionUpdateItem;
import com.elysia.newsservice.domain.vo.UpdateLogTotalVO;
import com.elysia.newsservice.domain.vo.VersionDetailVO;
import com.elysia.newsservice.enumeration.VersionUpdateCategoryEnum;
import com.elysia.newsservice.enumeration.VersionUpdateTypeEnum;
import com.elysia.newsservice.mapper.GameVersionMapper;
import com.elysia.newsservice.mapper.UpdateLogMapper;
import com.elysia.newsservice.mapper.VersionUpdateItemMapper;
import com.elysia.newsservice.result.Result;
import com.elysia.newsservice.service.IUpdateLogService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
@Slf4j
public class IUpdateLogServiceImpl implements IUpdateLogService {
    private final UpdateLogMapper updateLogMapper;
    private final GameVersionMapper gameVersionMapper;
    private final IVersionUpdateItemServiceImpl versionUpdateItemService;
    private final VersionUpdateItemMapper versionUpdateItemMapper;

    /**
     * 获取所有更新日志
     * @return 所有更新日志
     */
    @Override
    public Result<UpdateLogTotalVO> getAllUpdateLogs() {
        // 查询所有关联数据（主表+明细表）
        List<VersionJoinDTO> joinList = updateLogMapper.selectAllUpdateLogs();
        if (joinList.isEmpty()) {
            return Result.success();
        }

        // 按核心信息id分组：将同一版本的所有明细聚合到一起
        Map<Long, List<VersionJoinDTO>> versionGroup = joinList.stream()
                .collect(Collectors.groupingBy(VersionJoinDTO::getId));
        // 遍历每个版本，构建VersionDetailVO
        List<VersionDetailVO> allDetails = new ArrayList<>();
        for (Map.Entry<Long, List<VersionJoinDTO>> entry : versionGroup.entrySet()) {
            Long id = entry.getKey();
            List<VersionJoinDTO> versionItems = entry.getValue();

            // 取该版本的主表信息
            VersionJoinDTO firstItem = versionItems.get(0);
            VersionDetailVO detailVO = new VersionDetailVO();
            detailVO.setId(id);
            detailVO.setVersion(firstItem.getVersion());
            detailVO.setDate(firstItem.getUpdateDate());

            // 按明细类型拆分content
            List<String> newContent = versionItems.stream()
                    .filter(item -> item.getType() != null && item.getType().equals(VersionUpdateTypeEnum.NEW_CONTENT.getCode()))
                    .map(VersionJoinDTO::getContent)
                    .collect(Collectors.toList());

            List<String> optimizations = versionItems.stream()
                    .filter(item -> item.getType() != null && item.getType().equals(VersionUpdateTypeEnum.OPTIMIZATION.getCode()))
                    .map(VersionJoinDTO::getContent)
                    .collect(Collectors.toList());

            List<String> fixes = versionItems.stream()
                    .filter(item -> item.getType() != null && item.getType().equals(VersionUpdateTypeEnum.FIX.getCode()))
                    .map(VersionJoinDTO::getContent)
                    .collect(Collectors.toList());

            detailVO.setNewContent(newContent);
            detailVO.setOptimizations(optimizations);
            detailVO.setFixes(fixes);

            allDetails.add(detailVO);
        }

        // 按主表的update_category分类（从joinList中提取每个版本的分类）
        // 先构建版本号与分类的映射（避免重复计算）
        Map<Long, Integer> versionCategoryMap = joinList.stream()
                .collect(Collectors.toMap(
                        VersionJoinDTO::getId,
                        VersionJoinDTO::getUpdateCategory,
                        (existing, replacement) -> existing // 同一版本取第一个的分类
                ));
        // 拆分到UpdateLogTotalVO的三个列表
        UpdateLogTotalVO result = new UpdateLogTotalVO();
        result.setLatest(allDetails.stream()
                .filter(vo -> Objects.equals(versionCategoryMap.get(vo.getId()), VersionUpdateCategoryEnum.LATEST.getCode()))
                .collect(Collectors.toList()));

        result.setMajor(allDetails.stream()
                .filter(vo -> Objects.equals(versionCategoryMap.get(vo.getId()), VersionUpdateCategoryEnum.MAJOR.getCode()))
                .collect(Collectors.toList()));

        result.setBalance(allDetails.stream()
                .filter(vo -> Objects.equals(versionCategoryMap.get(vo.getId()), VersionUpdateCategoryEnum.BALANCE.getCode()))
                .collect(Collectors.toList()));
        return Result.success(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<UpdateLogTotalVO> addUpdateLog(UpdateLogDTO updateLogDTO) {
        // 校验版本号是否冲突
        if (gameVersionMapper.selectByVersion(updateLogDTO.getVersion()) != null)
            throw new IllegalArgumentException("该版本已存在");
        // 插入主表信息
        // 将Date转换为Instant（时间戳），再转为带时区的ZonedDateTime（默认系统时区）
        ZonedDateTime zonedDateTime = updateLogDTO.getDate().toInstant().atZone(ZoneId.systemDefault());

        // 2. 创建格式化器，指定模式yyyy-MM-dd
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 3. 格式化并转换为字符串
        String dateStr = zonedDateTime.format(formatter);
        GameVersion gameVersion = GameVersion.builder()
                        .version(updateLogDTO.getVersion())
                        .updateDate(dateStr)
                        .updateCategory(getVersionUpdateCategory(updateLogDTO.getCategory())).build();
        gameVersionMapper.insert(gameVersion);
        // 插入明细表信息
        List<VersionUpdateItem> itemList = new ArrayList<>();
        // 处理新增内容
        if (updateLogDTO.getNewContent() != null && !updateLogDTO.getNewContent().isEmpty()) {
            updateLogDTO.getNewContent().forEach(content -> {
                itemList.add(VersionUpdateItem.builder()
                        .versionId(gameVersion.getId())
                        .type(VersionUpdateTypeEnum.NEW_CONTENT)
                        .content(content)
                        .build());
            });
        }
        if (updateLogDTO.getOptimizations() != null && !updateLogDTO.getOptimizations().isEmpty()) {
            updateLogDTO.getOptimizations().forEach(content -> {
                itemList.add(VersionUpdateItem.builder()
                        .versionId(gameVersion.getId())
                        .type(VersionUpdateTypeEnum.OPTIMIZATION)
                        .content(content)
                        .build());
            });
        }
        if (updateLogDTO.getFixes() != null && !updateLogDTO.getFixes().isEmpty()) {
            updateLogDTO.getFixes().forEach(content -> {
                itemList.add(VersionUpdateItem.builder()
                        .versionId(gameVersion.getId())
                        .type(VersionUpdateTypeEnum.FIX)
                        .content(content)
                        .build());
            });
        }

        // 批量插入
        if (!itemList.isEmpty()) {
            versionUpdateItemService.saveBatch(itemList);
        }
        return getAllUpdateLogs();
    }

    /**
     * 删除更新日志
     * @param id 更新日志ID
     * @return 删除结果
     */
    @Override
    public Result<String> deleteUpdateLog(Long id) {
        // 删除更新明细
        versionUpdateItemMapper.deleteByVersionId(id);
        // 删除更新日志
        gameVersionMapper.deleteById(id);
        return Result.success("删除成功");
    }

    @Override
    public Result<String> updateUpdateLog(Long id, UpdateLogDTO updateLogDTO) {
        ZonedDateTime zonedDateTime = updateLogDTO.getDate().toInstant().atZone(ZoneId.systemDefault());
        // 创建格式化器，指定模式yyyy-MM-dd
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 格式化并转换为字符串
        String dateStr = zonedDateTime.format(formatter);
        GameVersion gameVersion = GameVersion.builder()
                .id(id)
                .version(updateLogDTO.getVersion())
                .updateDate(dateStr)
                .updateCategory(getVersionUpdateCategory(updateLogDTO.getCategory())).build();
        gameVersionMapper.updateById(gameVersion);
        // 插入明细表信息
        List<VersionUpdateItem> itemList = new ArrayList<>();
        // 处理新增内容
        if (updateLogDTO.getNewContent() != null && !updateLogDTO.getNewContent().isEmpty()) {
            updateLogDTO.getNewContent().forEach(content -> {
                itemList.add(VersionUpdateItem.builder()
                        .versionId(gameVersion.getId())
                        .type(VersionUpdateTypeEnum.NEW_CONTENT)
                        .content(content)
                        .build());
            });
        }
        if (updateLogDTO.getOptimizations() != null && !updateLogDTO.getOptimizations().isEmpty()) {
            updateLogDTO.getOptimizations().forEach(content -> {
                itemList.add(VersionUpdateItem.builder()
                        .versionId(gameVersion.getId())
                        .type(VersionUpdateTypeEnum.OPTIMIZATION)
                        .content(content)
                        .build());
            });
        }
        if (updateLogDTO.getFixes() != null && !updateLogDTO.getFixes().isEmpty()) {
            updateLogDTO.getFixes().forEach(content -> {
                itemList.add(VersionUpdateItem.builder()
                        .versionId(gameVersion.getId())
                        .type(VersionUpdateTypeEnum.FIX)
                        .content(content)
                        .build());
            });
        }
        if (!itemList.isEmpty()) {
            versionUpdateItemMapper.deleteByVersionId(id);
            versionUpdateItemService.saveBatch(itemList);
        }
        return Result.success("更新成功");
    }

    private VersionUpdateCategoryEnum getVersionUpdateCategory(String category){
        return switch (category) {
            case "latest" -> VersionUpdateCategoryEnum.LATEST;
            case "major" -> VersionUpdateCategoryEnum.MAJOR;
            case "balance" -> VersionUpdateCategoryEnum.BALANCE;
            default -> throw new IllegalArgumentException("无效的更新类别");
        };
    }
}
